#include <stdio.h>
#include <stdlib.h>
#include "debug.h"

static int               trace_level;
static ac_trace_printer_t ac_trace_function;

void ac_trace_printer_default(int level, const char * str, va_list ap)
{
#ifdef AC_TRACE_ENABLE
	const char * s[MAX] = {
		"",								// OFF
		"\033[1;31m[error]\033[1;39m ", // ERROR
		"\e[1;33m[warning]\e[1;39m ",   // WARNING
		"\e[1;32m[info]\e[1;39m ",		// INFO
		"\e[1;35m[verbose]\e[1;39m ",	// VERBOSE
		"\e[1;36m[debug]\e[1;39m ",		// DEBUG
	};

	fprintf(stderr, "%s", s[level]);	
	// fprintf(stderr, "\e[1;36mfile:%s func:%s line:%d\e[1;39m\n", __FILE__, __FUNCTION__, __LINE__);	
	vfprintf(stderr, str, ap);
	fprintf(stderr, "\n");
#else
	(void)level, (void)str, (void)ap;
#endif
}

void ac_trace_setup(int level, ac_trace_printer_t printer)
{
	trace_level   = level;
	if (level < OFF)
		trace_level = OFF;
	else if (level > MAX)
		trace_level = MAX;
	ac_trace_function = printer;
}

void ac_trace(int level, const char * str, ...)
{
	if(level && level <= trace_level && ac_trace_function) {
		va_list ap;
		va_start(ap, str);
		ac_trace_function(level, str, ap);
		va_end(ap);
	}
}

int ac_trace_get_level(void)
{
	return trace_level;
}

/*
 * Printer function for IDD message facility
 */
static void _ac_trace(int level, const char * str, va_list ap)
{
#ifdef AC_TRACE_ENABLE
	static char out_str[512]; /* static to limit stack usage */
	unsigned idx = 0;
	const char * ptr = out_str;
	const char * s[MAX] = {
		"",								// OFF
		"\033[1;31m[error]\033[1;39m ", // ERROR
		"\e[1;33m[warning]\e[1;39m ",   // WARNING
		"\e[1;32m[info]\e[1;39m ",		// INFO
		"\e[1;35m[verbose]\e[1;39m ",	// VERBOSE
		"\e[1;36m[debug]\e[1;39m ",		// DEBUG
	};

	idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "%s", s[level]);
	// idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "%s \e[1;36mfile:%s func:%s line:%d\e[1;39m \n",
	//						s[level],__FILE__, __FUNCTION__, __LINE__);
	if(idx >= (sizeof(out_str)))
		return;
	idx += vsnprintf(&out_str[idx], sizeof(out_str) - idx, str, ap);
	if(idx >= (sizeof(out_str)))
		return;
	idx += snprintf(&out_str[idx], sizeof(out_str) - idx, "\r\n");
	if(idx >= (sizeof(out_str)))
		return;

	while(*ptr != '\0') {
		putchar(*ptr);
		++ptr;
	}

#else
	(void)level, (void)str, (void)ap;
#endif
}



#if 1
void main()
{
	AC_TRACE_SETUP(TRACE_LEVEL, _ac_trace);

	AC_TRACE(DEBUG, "xiaozhi");
	AC_TRACE(INFO, "%d", 999);
	AC_TRACE(ERROR, "%d", ac_trace_get_level());
	AC_TRACE(WARNING, "%d", ac_trace_get_level());
	AC_TRACE(VERBOSE, "%d", ac_trace_get_level());

	AC_TRACE_SETUP(TRACE_LEVEL, ac_trace_printer_default);
	AC_TRACE(DEBUG, "xiaozhi");
	AC_TRACE(INFO, "%d", 999);
}
#endif
